import { createNextAnimateFrameEvent, Destroyable, extendClassProps, reactArray, reactArrayWithUndefined, ReactivePropsToNativePropsAndChanged } from "xbsj-base";
import { ESJVector3D, ESJVector4D, geoRhumbDestination } from "earthsdk3";
import { CzmPolyline } from "@czmSrc/CzmObjects";
import { ESCesiumViewer } from "@czmSrc/index";

function createAxis(czmViewer: ESCesiumViewer, color: ESJVector4D) {
    const axis = new CzmPolyline(czmViewer);
    axis.hasArrow = true;
    axis.arcType = 'RHUMB';
    axis.width = 10;
    axis.color = color;
    return axis;
}
/**
 * 坐标架,通过箭头线实现
 */
export class GeoCoordinates extends Destroyable {
    static defaults = {
        // show: true as boolean, // boolean} [show=true] A boolean Property specifying the visibility of the box.
        position: [116.39, 39.9, 0] as ESJVector3D, // 经度纬度高度，度为单位
        heading: 0 as number, // 偏航角，度为单位
        dimensions: [1000, 1000, 1000] as ESJVector3D, // Cartesian3} [dimensions] A {@link Cartesian3} Property specifying the length, width, and height of the box.
        xAxisColor: [1, 0, 0, 1] as ESJVector4D,
        yAxisColor: [0, 1, 0, 1] as ESJVector4D,
        zAxisColor: [0, 0, 1, 1] as ESJVector4D,
    };

    constructor(czmViewer: ESCesiumViewer) {
        super();
        if (!czmViewer.viewer) return;
        const xAxis = this.disposeVar(createAxis(czmViewer, GeoCoordinates.defaults.xAxisColor));
        const yAxis = this.disposeVar(createAxis(czmViewer, GeoCoordinates.defaults.yAxisColor));
        const zAxis = this.disposeVar(createAxis(czmViewer, GeoCoordinates.defaults.zAxisColor));
        {
            const updateProp = () => {
                xAxis.show = this.xAxisShow && this.show;
                yAxis.show = this.yAxisShow && this.show;
                zAxis.show = this.zAxisShow && this.show;
            };
            updateProp();
            const event = this.ad(createNextAnimateFrameEvent(
                this.showChanged,
                this.xAxisShowChanged,
                this.yAxisShowChanged,
                this.zAxisShowChanged
            ))
            this.dispose(event.disposableOn(updateProp));
        }
        {
            const updateProp = () => {
                const {
                    position = GeoCoordinates.defaults.position,
                    heading = GeoCoordinates.defaults.heading,
                } = this;
                const [l, b, h] = position;
                const { dimensions = GeoCoordinates.defaults.dimensions } = this;
                zAxis.positions = [position, [l, b, h + dimensions[2]]];
                const xd = geoRhumbDestination(position, dimensions[0], 90 + heading);
                xd && (xAxis.positions = [position, xd]);
                const yd = geoRhumbDestination(position, dimensions[1], 0 + heading);
                yd && (yAxis.positions = [position, yd]);
            };
            updateProp();
            const nfe = this.disposeVar(createNextAnimateFrameEvent(this.positionChanged, this.dimensionsChanged, this.headingChanged));
            this.dispose(nfe.disposableOn(updateProp));
        }
        {
            const updateProp = () => {
                xAxis.color = this.xAxisColor ?? GeoCoordinates.defaults.xAxisColor;
                yAxis.color = this.yAxisColor ?? GeoCoordinates.defaults.yAxisColor;
                zAxis.color = this.zAxisColor ?? GeoCoordinates.defaults.zAxisColor;
            };
            updateProp();
            const nfe = this.disposeVar(createNextAnimateFrameEvent(this.xAxisColorChanged, this.yAxisColorChanged, this.zAxisColorChanged));
            this.dispose(nfe.disposableOn(updateProp));
        }
    }
}

export namespace GeoCoordinates {
    export const createDefaultProps = () => ({
        show: true, // boolean} [show=true] A boolean Property specifying the visibility of the box.
        position: reactArrayWithUndefined<ESJVector3D | undefined>(undefined),
        heading: 0, // 偏航角，度为单位
        dimensions: reactArray<ESJVector3D>([1000, 1000, 1000]), // Cartesian3} [dimensions] A {@link Cartesian3} Property specifying the length, width, and height of the box.
        xAxisColor: reactArray<ESJVector4D>([1, 0, 0, 1]),
        yAxisColor: reactArray<ESJVector4D>([0, 1, 0, 1]),
        zAxisColor: reactArray<ESJVector4D>([0, 0, 1, 1]),
        xAxisShow: true,
        yAxisShow: true,
        zAxisShow: true,
    });
}
extendClassProps(GeoCoordinates.prototype, GeoCoordinates.createDefaultProps);
export interface GeoCoordinates extends ReactivePropsToNativePropsAndChanged<ReturnType<typeof GeoCoordinates.createDefaultProps>> { }
